import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';

class StreamBuilderGameDemo extends StatefulWidget {
  const StreamBuilderGameDemo({Key? key}) : super(key: key);

  @override
  _StreamBuilderGameDemoState createState() => _StreamBuilderGameDemoState();
}

class _StreamBuilderGameDemoState extends State<StreamBuilderGameDemo> {
  final StreamController<int> _inputController =
      StreamController.broadcast(); // 可以有多个监听者
  final StreamController<int> _scoreController = StreamController.broadcast();
  int score = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: StreamBuilder(
          stream: _scoreController.stream,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text("Error: ${snapshot.error}");
            }
            if (snapshot.hasData) {
              score = score + (snapshot.data as int);
              return Text("得分: $score");
            }
            return const Text("等待输入");
          },
        ),
      ),
      body: Stack(
        children: [
          ...List.generate(3, (index) {
            return Game(
                inputController: _inputController,
                scoreController: _scoreController);
          }),
          Align(
            alignment: Alignment.bottomCenter,
            child: KeyPad(controller: _inputController),
          )
        ],
      ),
    );
  }
}

// 算数子组件
class Game extends StatefulWidget {
  final StreamController<int> inputController;
  final StreamController<int> scoreController;

  // const Game({Key? key}) : super(key: key);
  const Game(
      {super.key,
      required this.inputController,
      required this.scoreController});

  @override
  _GameState createState() => _GameState();
}

class _GameState extends State<Game> with SingleTickerProviderStateMixin {
  late int a, b;
  late double x;
  late Color color;
  late AnimationController _animationController;

  void reset() {
    a = Random().nextInt(5) + 1;
    b = Random().nextInt(5);
    x = Random().nextDouble() * 320;
    color = Colors.primaries[Random().nextInt(Colors.primaries.length)];
  }

  @override
  void initState() {
    super.initState();

    reset();
    _animationController = AnimationController(
        vsync: this,
        duration: Duration(milliseconds: Random().nextInt(5000) + 5000));
    _animationController.forward(); // 执行一次动画

    _animationController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        // 监听动画执行完成
        // 生成随机数
        reset();
        widget.scoreController.add(-1); // 最底部减去1分
        _animationController.forward(from: 0.0); //重新执行一次动画
      }
    });

    widget.inputController.stream.listen((event) {
      if (a + b == event) {
        reset();
        widget.scoreController.add(3);
        _animationController.forward(from: 0.0);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
        animation: _animationController,
        builder: (context, child) {
          return Positioned(
              top: Tween(begin: -50.0, end: 560.0)
                  .animate(_animationController)
                  .value,
              left: x,
              child: Container(
                padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                decoration: BoxDecoration(
                    color: color, borderRadius: BorderRadius.circular(10)),
                child: Text("$a+$b=?", style: const TextStyle(fontSize: 25)),
              ));
        });
  }
}

// 键盘子组件
class KeyPad extends StatelessWidget {
  final StreamController<int> controller;
  const KeyPad({super.key, required this.controller});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: GridView.count(
        crossAxisCount: 3,
        shrinkWrap: true, // 收缩
        physics: const NeverScrollableScrollPhysics(), // 去掉ios中反弹效果
        childAspectRatio: 5 / 3,
        children: List.generate(9, (index) {
          return TextButton(
              style: ButtonStyle(
                  shape:
                      MaterialStateProperty.all(const RoundedRectangleBorder()),
                  foregroundColor: MaterialStateProperty.all(Colors.black),
                  backgroundColor:
                      MaterialStateProperty.all(Colors.primaries[index][400])),
              onPressed: () {
                controller.add(index + 1);
              },
              child:
                  Text("${index + 1}", style: const TextStyle(fontSize: 26)));
        }),
      ),
    );
  }
}
